import Router from 'koa-router';
import { SysUserRoleService } from '../../service/system/SysUserRole.js';
import {
  CreateSysUserRoleDto,
  UpdateSysUserRoleDto,
  SysUserRoleQueryDto,
} from '../../entities/system/SysUserRole.js';
import type { AppContext } from '../../types/index.js';
import { Response } from '../../utils/response.js';
import { BusinessException } from '../../types/exceptions.js';
import { ValidationUtil } from '../../utils/validation.js';

const router = new Router<Record<string, unknown>, AppContext>();

/**
 * 用户角色关联控制器
 * @description 使用单例模式，避免重复创建服务实例
 */
class UserRoleController {
  private static instance: UserRoleController;
  private readonly userRoleService: SysUserRoleService;

  private constructor() {
    this.userRoleService = new SysUserRoleService();
  }

  static getInstance(): UserRoleController {
    if (!UserRoleController.instance) {
      UserRoleController.instance = new UserRoleController();
    }
    return UserRoleController.instance;
  }

  /**
   * 创建用户角色关联
   * @param ctx - Koa应用上下文
   */
  async create(ctx: AppContext): Promise<void> {
    const userRole = ctx.request.body as CreateSysUserRoleDto;

    // 参数验证
    ValidationUtil.validateId(userRole.user_id as number, '用户ID');
    ValidationUtil.validateId(userRole.role_id as number, '角色ID');

    const userRoleId = await this.userRoleService.create(userRole);
    ctx.body = Response.success('创建成功', { id: userRoleId });
  }

  /**
   * 获取用户角色关联列表
   * @param ctx - Koa应用上下文
   */
  async list(ctx: AppContext): Promise<void> {
    const { page, pageSize, ...query } = ctx.query;
    const { pageNum, pageSizeNum } = ValidationUtil.validatePagination(
      page as string,
      pageSize as string
    );

    const result = await this.userRoleService.list(
      pageNum,
      pageSizeNum,
      query as SysUserRoleQueryDto
    );
    ctx.body = Response.success('获取成功', result);
  }

  /**
   * 更新用户角色关联
   * @param ctx - Koa应用上下文
   */
  async update(ctx: AppContext): Promise<void> {
    const id = ValidationUtil.validateId(ctx.params.id, 'ID');
    const userRole = ctx.request.body as UpdateSysUserRoleDto;

    if (Object.keys(userRole).length === 0) {
      throw new BusinessException('更新数据不能为空');
    }

    const success = await this.userRoleService.update(id, userRole);
    if (!success) {
      throw new BusinessException('更新失败，记录不存在或已被删除');
    }

    ctx.body = Response.success('更新成功');
  }

  /**
   * 删除用户角色关联
   * @param ctx - Koa应用上下文
   */
  async delete(ctx: AppContext): Promise<void> {
    const id = ValidationUtil.validateId(ctx.params.id, 'ID');

    const success = await this.userRoleService.delete(id);
    if (!success) {
      throw new BusinessException('删除失败，记录不存在或已被删除');
    }

    ctx.body = Response.success('删除成功');
  }

  /**
   * 根据ID获取用户角色关联详情
   * @param ctx - Koa应用上下文
   */
  async getById(ctx: AppContext): Promise<void> {
    const id = ValidationUtil.validateId(ctx.params.id, 'ID');

    const userRole = await this.userRoleService.getById(id);
    if (!userRole) {
      throw new BusinessException('记录不存在');
    }

    ctx.body = Response.success('获取成功', userRole);
  }

  /**
   * 根据用户ID获取角色关联
   * @param ctx - Koa应用上下文
   */
  async getByUserId(ctx: AppContext): Promise<void> {
    const userId = ValidationUtil.validateId(ctx.params.userId, '用户ID');

    const userRoles = await this.userRoleService.getByUserId(userId);
    ctx.body = Response.success('获取成功', userRoles);
  }

  /**
   * 根据角色ID获取用户关联
   * @param ctx - Koa应用上下文
   */
  async getByRoleId(ctx: AppContext): Promise<void> {
    const roleId = ValidationUtil.validateId(ctx.params.roleId, '角色ID');

    const userRoles = await this.userRoleService.getByRoleId(roleId);
    ctx.body = Response.success('获取成功', userRoles);
  }

  /**
   * 删除用户的所有角色关联
   * @param ctx - Koa应用上下文
   */
  async deleteByUserId(ctx: AppContext): Promise<void> {
    const userId = ValidationUtil.validateId(ctx.params.userId, '用户ID');

    const success = await this.userRoleService.deleteByUserId(userId);
    if (!success) {
      throw new BusinessException('删除失败，没有找到相关记录');
    }

    ctx.body = Response.success('删除成功');
  }

  /**
   * 删除角色的所有用户关联
   * @param ctx - Koa应用上下文
   */
  async deleteByRoleId(ctx: AppContext): Promise<void> {
    const roleId = ValidationUtil.validateId(ctx.params.roleId, '角色ID');

    const success = await this.userRoleService.deleteByRoleId(roleId);
    if (!success) {
      throw new BusinessException('删除失败，没有找到相关记录');
    }

    ctx.body = Response.success('删除成功');
  }
}

const controller = UserRoleController.getInstance();

/**
 * 路由定义
 */
router.post('/create', (ctx: AppContext) => controller.create(ctx));
router.get('/list', (ctx: AppContext) => controller.list(ctx));
router.put('/:id', (ctx: AppContext) => controller.update(ctx));
router.delete('/:id', (ctx: AppContext) => controller.delete(ctx));
router.get('/:id', (ctx: AppContext) => controller.getById(ctx));
router.get('/user/:userId', (ctx: AppContext) => controller.getByUserId(ctx));
router.get('/role/:roleId', (ctx: AppContext) => controller.getByRoleId(ctx));
router.delete('/user/:userId', (ctx: AppContext) => controller.deleteByUserId(ctx));
router.delete('/role/:roleId', (ctx: AppContext) => controller.deleteByRoleId(ctx));

export default router;
